﻿using Magicodes.ExporterAndImporter.Excel;
using Microsoft.Extensions.Configuration;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business.HYT;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.HYT.Dto;
using NP.BPMReportPlatform.Utilities;
using NP.BPMReportPlatform.Utils;
using Serilog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Users;
using NP.BPMReportPlatform.Reports.ZPSPXT.Dtos;
using System.IO;
using NP.BPMReportPlatform.Entities.BPM_Business.Reports;
using NP.BPMReportPlatform.Reports.OrderMaterialDetail.Dtos;
using System.Linq;

namespace NP.BPMReportPlatform.Reports.ZPSPXT
{
    public class ZPSPXTConfigService : BPMReportPlatformAppService, IZPSPXTConfigService
    {
        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly SqlSugarClient _dbEngine;
        private readonly ILogger _logger;
        private readonly IExcelImporter _importer;
        private readonly IConfiguration _configuration;
        public ZPSPXTConfigService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp, ILogger logger, IExcelImporter importer
            , IConfiguration configuration)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
            _logger = logger;
            _importer = importer;
            _configuration = configuration;
        }

        public async Task<PagedResultDto<ZPSPXTConfigDto>> GetAllAsync(ZPSPXTConfigInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            //返回结果
            return new PagedResultDto<ZPSPXTConfigDto>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<ZPSPXTConfigDto>> ExportAsync(ZPSPXTConfigInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        /// <summary>
        /// 获取Queryable(报表展现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<ZPSPXTConfigDto> GetQueryable(ZPSPXTConfigInput input)
        {
            var listQueryable = _db.Queryable<ZPSPXTConfig>().OrderBy(ins => ins.AddTime, OrderByType.Desc)
                .WhereIF(!string.IsNullOrEmpty(input.OrgCode), x => x.OrgCode == input.OrgCode)
                .WhereIF(!string.IsNullOrEmpty(input.OrgName), x => x.OrgName.Contains(input.OrgName))
                .Select(x => new ZPSPXTConfigDto
                {
                    Id = x.Id,
                    OrgCode = x.OrgCode,
                    OrgName = x.OrgName,
                    OrgUnitFormal = x.OrgUnitFormal,
                    OrgUnitLabor = x.OrgUnitLabor,
                    AddTime = x.AddTime,
                    AddWorkNumber = x.AddWorkNumber,
                    UpdateTime = x.UpdateTime,
                    UpdateWorkNumber = x.UpdateWorkNumber
                });
            return listQueryable;
        }

        public async Task Delete(Guid id)
        {
            await _db.Deleteable<ZPSPXTConfig>().Where(x => x.Id == id).ExecuteCommandAsync();
        }

        public async Task Edit(ZPSPXTConfigEditInput input)
        {
            if (!input.Id.HasValue || input.Id == Guid.Empty)
            {
                await _db.Insertable(new ZPSPXTConfig
                {
                    Id = Guid.NewGuid(),
                    OrgCode = input.OrgCode,
                    OrgName = input.OrgName,
                    OrgUnitFormal = input.OrgUnitFormal,
                    OrgUnitLabor = input.OrgUnitLabor,
                    AddTime = DateTime.Now,
                    AddWorkNumber = CurrentUser.UserName,
                }).ExecuteCommandAsync();
            }
            else
            {
                var entity = await _db.Queryable<ZPSPXTConfig>().FirstAsync(x => x.Id == input.Id);
                if (entity == null)
                {
                    throw new Exception("数据未找到");
                }

                entity.OrgCode = input.OrgCode;
                entity.OrgName = input.OrgName;
                entity.OrgUnitFormal = input.OrgUnitFormal;
                entity.OrgUnitLabor = input.OrgUnitLabor;
                entity.UpdateTime = DateTime.Now;
                entity.UpdateWorkNumber = CurrentUser.UserName;
                await _db.Updateable(entity).ExecuteCommandAsync();
            }
        }

        public async Task<FileStream> ExportTemplate()
        {
            var fileName = Environment.CurrentDirectory + "/wwwroot/excel/招聘审批系统配置表导入模板.xlsx";
            if (File.Exists(fileName))
            {
                return File.OpenRead(fileName);
            }
            else
            {
                throw new Exception("文件未找到");
            }
        }

        public async Task<ImportResultExt<ZPSPXTConfigDto>> ImportExcel(List<ZPSPXTConfigDto> data)
        {
            var rst = new ImportResultExt<ZPSPXTConfigDto>
            {
                Data = data
            };

            var updateEntities = new List<ZPSPXTConfig>();
            var addEntitie = new List<ZPSPXTConfig>();
            var exsitDatas = await _db.Queryable<ZPSPXTConfig>().ToListAsync();
            var index = 2;
            foreach (var item in data)
            {
                if (string.IsNullOrWhiteSpace(item.OrgCode))
                {
                    rst.Exception = new Exception($"第{index}行，请填写组织编码");
                    break;
                }
                if (data.Count(x => x.OrgCode == item.OrgCode) > 1)
                {
                    rst.Exception = new Exception($"第{index}行，组织编码有重复");
                    break;
                }

                var exsitData = exsitDatas.FirstOrDefault(x => x.OrgCode == item.OrgCode);
                if (exsitData != null)
                {
                    exsitData.OrgName = item.OrgName;
                    exsitData.OrgUnitFormal = item.OrgUnitFormal?.Trim();
                    exsitData.OrgUnitLabor = item.OrgUnitLabor?.Trim();
                    exsitData.UpdateWorkNumber = CurrentUser.UserName;
                    exsitData.UpdateTime = DateTime.Now;
                    updateEntities.Add(exsitData);
                }
                else
                {
                    addEntitie.Add(new ZPSPXTConfig
                    {
                        OrgCode = item.OrgCode,
                        OrgName = item.OrgName,
                        OrgUnitFormal = item.OrgUnitFormal,
                        OrgUnitLabor = item.OrgUnitLabor,
                        AddTime = DateTime.Now,
                        AddWorkNumber = CurrentUser.UserName
                    });
                }

                index++;
            }

            if (rst.HasError)
            {
                return new ImportResultExt<ZPSPXTConfigDto>()
                {
                    Exception = rst.Exception,
                    RowErrors = rst.RowErrors,
                    TemplateErrors = rst.TemplateErrors
                };
            }

            try
            {
                _db.BeginTran();

                await _db.Updateable(updateEntities).ExecuteCommandAsync();

                await _db.Insertable(addEntitie).ExecuteCommandAsync();

                _db.CommitTran();
            }
            catch (Exception ex)
            {
                rst.Exception = new Exception(ex.Message);
                _db.RollbackTran();
            }

            var resp = new ImportResultExt<ZPSPXTConfigDto>()
            {
                Exception = rst.Exception,
                RowErrors = rst.RowErrors,
                TemplateErrors = rst.TemplateErrors
            };
            return resp;
        }
    }
}
